home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / Little Smalltalk v3.1.4 / C Source / Sources / glue1.cp < prev    next >
Encoding:
Text File  |  1995-01-26  |  22.1 KB  |  736 lines  |  [TEXT/KAHL]

  1. /*
  2.     Little Smalltalk, version 3
  3.     Written by Tim Budd, Oregon State University, June 1988
  4.  
  5.     Symantec Think Class Library interface code 
  6.         ©Julian Barkway, April 1994, all rights reserved. 
  7.     
  8.     glue1.cp 
  9.     --------
  10.     
  11.     This is the interface between Little Smalltalk and the Symantec Think 
  12.     Class Library (v1.1.3). Where possible, I have retained the StdWin 
  13.     function names and parameters used in the original Little Smalltalk (v3) 
  14.     (although certain structures now refer to TCL objects) in order to assist 
  15.     porting. 
  16.     
  17.     Glue1.cp contains functions relating to windows, menus, graphics and dialogues.
  18.     Glue2.cp contains text, event handling and general purpose functions.
  19. */
  20.  
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "Callbacks.proto.h"
  24. #include "TBUtilities.h"
  25. #include "Constants.h"
  26. #include "Global.h"
  27. #include "CBartender.h"
  28. #include "CLStWindow.h"
  29. #include "CLStApp.h"
  30. #include "CLStDoc.h"
  31. #include "CGraphicsPane.h"
  32. #include "LStResources.h"
  33. #include "env.h"
  34. #include "memory.h"
  35. #include "macio.h"
  36.  
  37.                     // 'class' was redefined as 'klass' in order to avoid conflicts 
  38.                     // with the synonymous Think-C reserved word. Now the new definition 
  39.                     // must be removed in order to use TCL functions...
  40. #undef class
  41. #include "glue.h"
  42.  
  43. extern CBartender    *gBartender;
  44. extern CLStApp        *gSmalltalk;
  45.  
  46. #define uchar    unsigned char
  47.  
  48. //===================================================================================
  49. // Initialise the host windowing facility.
  50. //===================================================================================
  51. void winit (void)
  52. {
  53.     gSmalltalk = new (CLStApp);
  54.     gSmalltalk->ILStApp ();
  55.     if (gSystem.systemVersion < 0x0700) {
  56.         wperror ("Sorry, but System-7 or later is required to run Little Smalltalk.");
  57.         abort ();
  58.     }
  59. }
  60.  
  61.  
  62. //===================================================================================
  63. // Return the current version number as a 'C' string.
  64. //===================================================================================
  65. void getVersionNumber (char *str)
  66. {
  67.     PtoCstr (gSmalltalk->versionStr);
  68.     strcpy  (str, gSmalltalk->versionStr);
  69.     CtoPstr (gSmalltalk->versionStr);
  70. }
  71.  
  72.  
  73. //===================================================================================
  74. // Perform any necessary shut-down protocol for the host windowing facility.
  75. //===================================================================================
  76. void wdone (void)
  77. {
  78.     return;
  79. }
  80.  
  81.  
  82. //===================================================================================
  83. // Display a message to the user.
  84. //===================================================================================
  85. void wmessage (char *prompt)
  86. {
  87.     gSmalltalk->DoMessageAlert (prompt);
  88. }
  89.  
  90.  
  91. //===================================================================================
  92. // Display an error alert to the user.
  93. //===================================================================================
  94. void wperror (char *name)
  95. {
  96.     CtoPstr        (name);
  97.     ParamText      ((uchar *)name, NULL, NULL, NULL);
  98.     PositionDialog ('ALRT', ALRTgeneral);
  99.     InitCursor     ();
  100.     Alert          (ALRTgeneral, NULL);
  101.     PtoCstr        ((uchar *)name);
  102. }
  103.  
  104.  
  105. //=====================================================================================
  106. // Put up a prompt requesting some text from the user.
  107. //=====================================================================================
  108. Boolean waskstr (char *prompt, char *buf, int len)
  109. {
  110.     DialogPtr            theDialog;
  111.     GrafPtr                savePort;
  112.     short                itemHit, iType;
  113.     Handle                iText;
  114.     Rect                iRect;
  115.     Str255                boxText;
  116.     Boolean                rc;    
  117.     
  118.     GetPort (&savePort);
  119.     theDialog = GetNewDialog (kAskStringDLOG, 0L, (WindowPtr)-1L);
  120.     if (!theDialog) {
  121.         SetPort (savePort);
  122.         return (FALSE);
  123.     }
  124.  
  125.     CtoPstr   (prompt);
  126.     ParamText ((uchar *)prompt, NULL, NULL, NULL);
  127.     
  128.     GetDItem (theDialog, 5, &iType, &iText, &iRect);
  129.     SetDItem (theDialog, 5, iType, (Handle)highlightButton, &iRect);
  130.     GetDItem (theDialog, 4, &iType, &iText, &iRect);
  131.     
  132.     while (itemHit != OK && itemHit != Cancel) {
  133.         ModalDialog (defaultButtonFilter, &itemHit );
  134.     }
  135.     if (itemHit == Cancel)
  136.         rc = FALSE;
  137.     else {
  138.         GetIText (iText, boxText); 
  139.         PtoCstr (boxText);
  140.         strcpy (buf, (char *)boxText);        
  141.         rc = TRUE;
  142.     }    
  143.  
  144.     DisposDialog (theDialog);
  145.     SetPort      (savePort);
  146.     PtoCstr      ((uchar *)prompt);
  147.     return rc;
  148. }
  149.  
  150.  
  151. //===================================================================================
  152. // Display a message to the user requiring a Yes, No or Cancel response.
  153. //===================================================================================
  154. int waskync    (char *prompt, int def)
  155. {
  156.     return ((int)gSmalltalk->DoYNCAlert (prompt));
  157. }
  158.  
  159.  
  160. //===================================================================================
  161. // Display the standard file name requester. 
  162. // ---Parameter ftype added to StdWin function prototype.
  163. //===================================================================================
  164. Boolean waskfile (char *prompt, char *buf, int len, Boolean newFile, short ftype)
  165. {
  166.     WindowRecord        *w;
  167.     CLStWindow            *stWin;
  168.     CLStDoc                *doc;
  169.     StandardFileReply    fileStuff;
  170.     SFTypeList            fileTypes;
  171.     short                numTypes = 1;
  172.  
  173.     w = (WindowRecord *)FrontWindow ();
  174.     if (! w)
  175.         doc = new (CLStDoc);
  176.     else {
  177.         stWin = (CLStWindow *)GetWRefCon ((WindowPtr)w);
  178.         doc   = (CLStDoc *)(stWin->theLStWindow)->document;
  179.     }
  180.     
  181.     if (newFile)
  182.         doc->AskFileName (prompt, newFile, &fileStuff, NULL, 0);
  183.     else {    
  184.         stFileTypeToMac (ftype, fileTypes [0]);
  185.         if (fileTypes [0] == 0L) {
  186.             numTypes = -1;    /* If type not specified, then don't apply filtering */
  187.             doc->AskFileName (prompt, newFile, &fileStuff, NULL, numTypes);
  188.         }
  189.         else
  190.             doc->AskFileName (prompt, newFile, &fileStuff, fileTypes, numTypes);
  191.     }
  192.     if (fileStuff.sfGood == FALSE) 
  193.         return FALSE;
  194.     
  195.     PtoCstr     (fileStuff.sfFile.name);
  196.     getPathName (fileStuff.sfFile.vRefNum, fileStuff.sfFile.parID, buf);
  197.     strcat      (buf, (char *)fileStuff.sfFile.name);
  198.     return TRUE;
  199. }
  200.  
  201.  
  202. //===================================================================================
  203. // Enable (un-dim) an entire menu
  204. //===================================================================================
  205. void wmenuenable (MENU *mp, int item, int flag)
  206. {
  207.     if (flag)
  208.         EnableItem ((MenuHandle)mp, item + 1);
  209.     else
  210.         DisableItem ((MenuHandle)mp, item + 1);
  211. }
  212.  
  213.  
  214. //===================================================================================
  215. // Create a new menu.
  216. //===================================================================================
  217. MENU *wmenucreate (int id, char *title)
  218. {
  219.     MenuHandle        mh;
  220.     
  221.     id += kSTMenuBase;    // Our MENU resource ids start at 50. Smalltalk uses 1 - 15
  222.                         // Unfortunately, TCL also uses 1 - 5, hence this kludge.
  223.     gBartender->AddMenu (id, FALSE, 0);
  224.     ((CBartender *)gBartender)->SetDimOption (id, dimNONE);
  225.     mh = gBartender->FindMacMenu (id);
  226.     (*mh)->menuID = id;
  227.     return (MenuPtr)mh;
  228. }
  229.  
  230.  
  231. //===================================================================================
  232. // Create a pop-up menu. Pop-up menus are not handled through TCL and are created
  233. // without the need for a resource file entry.  Not a StdWin function. 
  234. //===================================================================================
  235. MENU *popUpMenuCreate (short menuID)
  236. {
  237.     menuID += kSTPopMenuBase;
  238.     return (MenuPtr)NewMenu (menuID, "\p");
  239. }
  240.  
  241.  
  242. //===================================================================================
  243. // Attach a menu to a window.
  244. //===================================================================================
  245. void wmenuattach (WINDOW *win, MENU *mp)
  246. {
  247.     MenuHandle    mh;
  248.     short        menuID;
  249.     
  250.     mh     = (MenuHandle)mp;
  251.     menuID = (*mh)->menuID;
  252.     ((CBartender *)gBartender)->InsertInBar (menuID, 0);
  253. }
  254.  
  255.  
  256. //===================================================================================
  257. // Detach a menu from a window.
  258. //===================================================================================
  259. void wmenudetach (WINDOW *win, MENU *mp)
  260. {
  261.     MenuHandle    mh;
  262.     short        menuID;
  263.     
  264.     mh     = (MenuHandle)mp;
  265.     menuID = (*mh)->menuID;
  266.     gBartender->DeleteFromBar (menuID);
  267. }
  268.  
  269.  
  270. //===================================================================================
  271. // Check mark an item.
  272. //===================================================================================
  273. void wmenucheck    (MENU *mp, int item, int flag)
  274. {
  275.     CheckItem ((MenuHandle)mp, item + 1, flag);
  276. }
  277.  
  278.  
  279. //===================================================================================
  280. // Stub function for StdWin compatibility.
  281. //===================================================================================
  282. void wmenusetdeflocal (Boolean local)
  283. {
  284.     return;
  285. }
  286.  
  287.  
  288. //===================================================================================
  289. // Append an item to the end of a menu.
  290. //===================================================================================
  291. int wmenuadditem (MENU *mp, char *text, int shortcut)
  292. {
  293.     CtoPstr (text);
  294.     AppendMenu ((MenuHandle)mp, (uchar *)text);
  295.     PtoCstr ((uchar *)text);
  296.     return (1);
  297. }
  298.  
  299.  
  300. //===================================================================================
  301. // Select an item from a pop-up menu displayed at top, left.  Not a StdWin function. 
  302. //===================================================================================
  303. void selectFromPopUpMenu (MENU *mp, short top, short left, short *menu, short *item)
  304. {
  305.     MenuHandle    mh;
  306.     long        selection;
  307.     Point        p;
  308.     
  309.     mh = (MenuHandle)mp;
  310.     p.h = left;
  311.     p.v = top;
  312.     ((CLStWindow *)GetWRefCon (FrontWindow () ))->Prepare ();
  313.     LocalToGlobal (&p);
  314.     InsertMenu (mh, hierMenu);
  315.     selection = PopUpMenuSelect (mh, p.v, p.h, 1);
  316.  
  317.     if (HiWord (selection ) == 0)
  318.         *menu = *item = 0;
  319.     else {
  320.         *menu = HiWord (selection);
  321.         *item = LoWord (selection);
  322.     }        
  323. }
  324.  
  325.  
  326. //===================================================================================
  327. // Completely dispose of a menu.
  328. //===================================================================================
  329. void wmenudelete (MENU *mp)
  330. {
  331.     MenuHandle    mh;
  332.     short        menuID;
  333.     
  334.     mh     = (MenuHandle)mp;
  335.     menuID = (*mh)->menuID;
  336.     gBartender->RemoveMenu (menuID);
  337. }
  338.  
  339.  
  340. //===================================================================================
  341. // Remove a menu item. Not a StdWin function.
  342. //===================================================================================
  343. void removeMenuItem (MENU *mp, short menuItem)
  344. {
  345.     DelMenuItem ((MenuHandle)mp, menuItem);
  346. }
  347.  
  348.  
  349. //===================================================================================
  350. // Return four values representing the pixel co-ords of the left, top, right and 
  351. // bottom of the maximum available screen are respectively.  Not a StdWin function. 
  352. //===================================================================================
  353. void getMaxScreenArea (short *left, short *top, short *right, short *bottom)
  354. {
  355.     *left   = screenBits.bounds.left;
  356.     *top    = screenBits.bounds.top;
  357.     *right  = screenBits.bounds.right;
  358.     *bottom = screenBits.bounds.bottom;
  359. }
  360.  
  361.  
  362. //===================================================================================
  363. // Return the named cursor from a resource or the system. 
  364. //===================================================================================
  365. CURSOR *wfetchcursor (char *name)
  366. {
  367.     CursHandle csrH;
  368.     
  369.     if (strcmp (name, "ibeam") == 0)
  370.         csrH = GetCursor (iBeamCursor);
  371.     else if (strcmp (name, "cross") == 0)
  372.         csrH = GetCursor (crossCursor);
  373.     else if (strcmp (name, "plus") == 0)
  374.         csrH = GetCursor (plusCursor);
  375.     else if (strcmp (name, "watch") == 0)
  376.         csrH = GetCursor (watchCursor);
  377.     else if (strcmp (name, "arrow") == 0)
  378.         csrH = (CursHandle)0xffffffffL;    /* A fairly unlikely handle. We'll use it as a flag. */
  379.     else
  380.         csrH = (CursHandle) GetNamedResource ('CURS', (uchar *)name);
  381.     
  382.     return (CURSOR *)csrH;
  383. }
  384.  
  385.  
  386. //===================================================================================
  387. // Set the current cursor to the given cursor. (Window is irrelevant here).
  388. //===================================================================================
  389. void wsetwincursor (WINDOW *win, CURSOR *cursor)
  390. {
  391.     Cursor    csr;
  392.     
  393.     if ((long)cursor == 0xffffffffL) {
  394.         InitCursor ();
  395.         return;
  396.     }
  397.     
  398.     HLock ((Handle)cursor);
  399.     csr = **((CursHandle)cursor);
  400.     HUnlock ((Handle)cursor);
  401.     SetCursor (&csr);
  402. }
  403.  
  404.  
  405. //===================================================================================
  406. // Restore the standard arrow pointer. Not a StdWin function.
  407. //===================================================================================
  408. void setArrowCursor (void)
  409. {
  410.     InitCursor ();
  411. }
  412.  
  413.  
  414. //===================================================================================
  415. // Query the dirty status of a document. Not a StdWin function.
  416. //===================================================================================
  417. Boolean docDirty (WINDOW *win)
  418. {
  419.     return ((CDocument *)win->document)->dirty;
  420. }
  421.  
  422.  
  423. //===================================================================================
  424. // Change the size of the given document.
  425. //===================================================================================
  426. void wsetdocsize (WINDOW *win, int docwidth, int docheight)
  427. {
  428.     ((CLStWindow *)win->window)->ChangeSize (docwidth, docheight);
  429. }
  430.  
  431.  
  432. //===================================================================================
  433. // Mark the given window as active.
  434. //===================================================================================
  435. void wsetactive    (WINDOW *win)
  436. {
  437.     ((CLStWindow *)win->window)->Activate ();
  438. }
  439.  
  440.  
  441. //===================================================================================
  442. // Open a window. Note that drawproc is redundant.
  443. //===================================================================================
  444. WINDOW *wopen (char *title, void (*drawproc)(WINDOW *win, int top, int left,
  445.                                               int bottom, int right) )
  446. {
  447.     CLStDoc    *doc;
  448.     WINDOW    *w;
  449.     
  450.     w   = (WINDOW *)malloc ((size_t)sizeof (WINDOW));
  451.     w->document = (char *)new (CLStDoc);
  452.     ((CLStDoc *)w->document)->ILStDoc (gSmalltalk, FALSE);
  453.     w->window   = (char *)((CLStDoc *)w->document)->BuildWindow (title, NULL, NULL);
  454.     ((CLStWindow *)w->window)->theLStWindow = w;
  455.     return w;
  456. }
  457.  
  458.  
  459. //===================================================================================
  460. // Open a window, given its location and size. Note: if the left, top and/or the
  461. // width/height parameter pairs are zero, values will be provided by the underlying
  462. // TCL routine. Not a StdWin function. 
  463. //===================================================================================
  464. WINDOW *wopentosize (char *title, int left, int top, int width, int height)
  465. {
  466.     CLStDoc    *doc;
  467.     WINDOW    *w;
  468.     Point    wPosition, wSize, *p, *s;
  469.     
  470.     w   = (WINDOW *)malloc ((size_t)sizeof (WINDOW));
  471.     w->document = (char *)new (CLStDoc);
  472.     ((CLStDoc *)w->document)->ILStDoc (gSmalltalk, FALSE);
  473.     if (left == 0 && top == 0)
  474.         p = NULL;
  475.     else {
  476.         wPosition.h = left;
  477.         wPosition.v = top;
  478.         p           = &wPosition;
  479.     }
  480.     if (width == 0 && height == 0)
  481.         s = NULL;
  482.     else {
  483.         wSize.h     = width;
  484.         wSize.v     = height;
  485.         s           = &wSize;
  486.     }
  487.     w->window   = (char *)((CLStDoc *)w->document)->BuildWindow (title, p, s);
  488.     ((CLStWindow *)w->window)->theLStWindow = w;
  489.     return w;
  490. }
  491.  
  492.  
  493. //===================================================================================
  494. // Close a window.
  495. //===================================================================================
  496. void wclose    (WINDOW *win)
  497. {
  498.     ((CLStWindow *)win->window)->Remove ();
  499. }
  500.  
  501.  
  502. //===================================================================================
  503. // Return the current size of a window.
  504. //===================================================================================
  505. void wgetwinsize (WINDOW *win, int *pwidth, int *pheight)
  506. {
  507.     LongRect    lr;
  508.     
  509.     ((CLStWindow *)win->window)->GetAperture (&lr);
  510.  
  511.     *pwidth  = lr.right - lr.left;
  512.     *pheight = lr.bottom - lr.top;
  513. }
  514.  
  515.  
  516. //===================================================================================
  517. // Return the current position (in global co-ordinates) of a window.
  518. //===================================================================================
  519. void wgetwinpos (WINDOW *win, int *h, int *v)
  520. {
  521.     Point        pt;
  522.     GrafPort    *port;
  523.  
  524.     port = ((CLStWindow *)(win->window))->macPort;
  525.     pt.h = port->portRect.left;
  526.     pt.v = port->portRect.top;
  527.     ((CLStWindow *)(win->window))->Prepare ();
  528.     LocalToGlobal(&pt);
  529.     *h = pt.h;
  530.     *v = pt.v;
  531. }
  532.  
  533.  
  534. //===================================================================================
  535. // Bring a window to the 'front'. Not a StdWin function.
  536. //===================================================================================
  537. void windowToFront (WINDOW *win)
  538. {
  539.     ((CLStWindow *)(win->window))->Select ();
  540. }
  541.  
  542.  
  543. //===================================================================================
  544. // Set a window's title.
  545. //===================================================================================
  546. void wsettitle (WINDOW *win, Str255 title)
  547. {
  548.     ((CLStWindow *)win->window)->SetTitle (title);
  549. }
  550.  
  551.  
  552. //===================================================================================
  553. // Stub function provided for StdWin compatitbility.
  554. //===================================================================================
  555. void wsetorigin (WINDOW *win, int orgh, int orgv)
  556. {
  557.     return;
  558. }
  559.  
  560.  
  561. //===================================================================================
  562. // Notify the system that we wish to commence a drawing operation.
  563. // - Slightly altered from the StdWin prototype to enable drawing to be 
  564. //   directed to a specific pane.
  565. //===================================================================================
  566. void wbegindrawing (TEXTEDIT *pane)
  567. {
  568.     ((CPane *)pane)->Prepare ();
  569. }
  570.  
  571.  
  572. //===================================================================================
  573. // Stub function provided for StdWin compatitbility.
  574. //===================================================================================
  575. void wenddrawing (TEXTEDIT *pane)
  576. {
  577.     return;
  578. }
  579.  
  580.  
  581. //===================================================================================
  582. // Beep the beeper.
  583. //===================================================================================
  584. void wfleep    (void)
  585. {
  586.     SysBeep (0);
  587. }
  588.  
  589.  
  590. //===================================================================================
  591. // Set the shading pattern for future drawing calls.
  592. //
  593. // Note: behaviour changed from StdWin prototype. Will now set the percentage
  594. //       of grey to be used in all drawing operations. Use wpaint () to colour
  595. //       a rectangle with the current pattern. This allows rather more flexibility.
  596. //
  597. //       5 percentage ranges are allowed corresponding to the five predefined 
  598. //       Mac Toolbox 'colours' as follows:
  599. //
  600. //        0 - 19% = white
  601. //       20 - 39% = ltGray
  602. //       40 - 59% = gray
  603. //       60 - 79% = dkGray
  604. //       80%+     = black
  605. //===================================================================================
  606. void wshade    (int left, int top, int right, int bottom, int perc)
  607. {
  608.     PatPtr    pat;
  609.     
  610.     if (perc >= 0 && perc < 20) {
  611.         pat = (PatPtr)white;
  612.     }
  613.     else if (perc > 20 && perc < 39) {
  614.         pat = (PatPtr)ltGray;
  615.     }
  616.     else if (perc > 40 && perc < 59) {
  617.         pat = (PatPtr)gray;
  618.     }
  619.     else if (perc > 60 && perc < 79) {
  620.         pat = (PatPtr)dkGray;
  621.     }
  622.     else {
  623.         pat = (PatPtr)black;
  624.     }
  625.     PenPat ((uchar const *)pat);
  626. }
  627.  
  628.  
  629. //===================================================================================
  630. // Erase the given rectangle.
  631. //===================================================================================
  632. void werase (int left, int top, int right, int bottom)
  633. {
  634.     Rect    r;
  635.     
  636.     SetRect     (&r, left, top, right, bottom);
  637.     EraseRect    (&r);
  638. }
  639.  
  640.  
  641. //===================================================================================
  642. // Draw a circle.
  643. //===================================================================================
  644. void wdrawcircle (int h, int v, int radius)
  645. {
  646.     Rect    r;
  647.     
  648.     SetRect     (&r, h - radius, v - radius, h + radius, v + radius);
  649.     FrameOval    (&r);
  650. }
  651.  
  652.  
  653. //===================================================================================
  654. // Draw a line from the current pen position to the given co-ordinates.
  655. // Not a StdWin function. 
  656. //===================================================================================
  657. void drawLineTo (int h, int v)
  658. {
  659.     LineTo (h, v);
  660. }
  661.  
  662.  
  663. //===================================================================================
  664. // Move the pen position to the given co-ordinates. Not a StdWin function. 
  665. //===================================================================================
  666. void moveTo (short h, short v)
  667. {
  668.     MoveTo (h, v);
  669. }
  670.  
  671.  
  672. //===================================================================================
  673. // Draw a pixel at the given co-ordinates. Not a StdWin function. 
  674. //===================================================================================
  675. void drawPixel (short h, short v)
  676. {
  677.     MoveTo (h, v);
  678.     LineTo (h, v);
  679. }
  680.  
  681.  
  682. //===================================================================================
  683. // Draw a box corresponding to the given co-ordinates.
  684. //===================================================================================
  685. void wdrawbox (int left, int top, int right, int bottom)
  686. {
  687.     Rect    r;
  688.     
  689.     SetRect     (&r, left, top, right, bottom);
  690.     FrameRect    (&r);
  691. }
  692.  
  693.  
  694. //===================================================================================
  695. // Invert all the pixels in a rectangular area.
  696. //===================================================================================
  697. void winvert (int left, int top, int right, int bottom)
  698. {
  699.     Rect    r;
  700.     
  701.     SetRect     (&r, left, top, right, bottom);
  702.     InvertRect    (&r);
  703. }
  704.  
  705.  
  706. //===================================================================================
  707. // Fill a rectangle with the current pattern.
  708. //===================================================================================
  709. void wpaint    (int left, int top, int right, int bottom)
  710. {
  711.     Rect    r;
  712.     
  713.     SetRect     (&r, left, top, right, bottom);
  714.     PaintRect    (&r);
  715. }
  716.  
  717.  
  718. //===================================================================================
  719. // Draw a character string at the given location.
  720. //===================================================================================
  721. void wdrawtext (int h, int v, char *str, int len)
  722. {
  723.     MoveTo        (h, v);
  724.     DrawText    (str, 0, len);
  725. }
  726.  
  727.  
  728. //===================================================================================
  729. // Draw a single character at the given location.
  730. //===================================================================================
  731. void wdrawchar (int h, int v, int c)
  732. {
  733.     MoveTo        (h, v);
  734.     DrawChar    ((char)c);
  735. }
  736.